home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 42 / Amiga Format AFCD42 (Issue 126, Aug 1999).iso / -serious- / comms / other / slrn / slrn_src / src / interp.c < prev    next >
C/C++ Source or Header  |  1999-05-14  |  25KB  |  1,125 lines

  1. /* -*- mode: C; mode: fold -*- */
  2. /* Copyright (c) 1998 John E. Davis (davis@space.mit.edu)
  3.  *
  4.  * This file is part of slrn.
  5.  *
  6.  * Slrn is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  * 
  11.  * Slrn is distributed in the hope that it will be useful, but WITHOUT
  12.  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13.  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14.  * for more details.
  15.  * 
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with Slrn; see the file COPYING.  If not, write to the Free
  18.  * Software Foundation, 59 Temple Place - Suite 330, 
  19.  * Boston, MA  02111-1307, USA.
  20.  */
  21.  
  22.  
  23. #include "config.h"
  24. #include "slrnfeat.h"
  25.  
  26. #include <stdio.h>
  27.  
  28. /* rest of file inside this #if statement */
  29. #if SLRN_HAS_SLANG
  30.  
  31. /*{{{ Include files */
  32.  
  33. #if HAVE_STDLIB_H
  34. # include <stdlib.h>
  35. #endif
  36. #include <string.h>
  37.  
  38. #include <slang.h>
  39. #include "jdmacros.h"
  40.  
  41. #include "slrn.h"
  42. #include "group.h"
  43. #include "art.h"
  44. #include "misc.h"
  45. #include "startup.h"
  46. #include "server.h"
  47. #include "menu.h"
  48. #include "interp.h"
  49. #include "util.h"
  50. #include "print.h"
  51.  
  52. /*}}}*/
  53.  
  54. /*{{{ Public Global Variables */
  55.  
  56. int Slrn_Use_Slang = 0;
  57. char *Slrn_Macro_Dir;
  58.  
  59. /*}}}*/
  60.  
  61.  
  62. /*{{{ Screen update and message functions */
  63.  
  64. static void error (char *msg) /*{{{*/
  65. {
  66.    slrn_error ("%s", msg);
  67. }
  68.  
  69. /*}}}*/
  70.  
  71. static void update (void) /*{{{*/
  72. {
  73.    slrn_update_screen ();
  74. }
  75. /*}}}*/
  76.  
  77. static void free_argv_list (char **argv, unsigned int argc)
  78. {
  79.    unsigned int i;
  80.    
  81.    for (i = 0; i < argc; i++)
  82.      slrn_free (argv[i]);
  83.    slrn_free ((char *) argv);
  84. }
  85.  
  86. static char **pop_argv_list (unsigned int *argcp)
  87. {
  88.    int n;
  89.    char **argv;
  90.    unsigned int i, argc;
  91.  
  92.    if (-1 == SLang_pop_integer (&n))
  93.      return NULL;
  94.  
  95.    if (n < 0)
  96.      {
  97.     slrn_error ("positive integer expected");
  98.     return NULL;
  99.      }
  100.  
  101.    argc = (unsigned int) n;
  102.       
  103.    if (NULL == (argv = (char **) slrn_malloc (sizeof (char *) * (argc + 1), 1, 1)))
  104.      {
  105.     SLang_Error = SL_MALLOC_ERROR;
  106.     return NULL;
  107.      }
  108.    
  109.    argv [n] = NULL;
  110.    i = argc;
  111.    while (i != 0)
  112.      {
  113.     i--;
  114.     if (-1 == SLpop_string (argv + i))
  115.       {
  116.          free_argv_list (argv, argc);
  117.          return NULL;
  118.       }
  119.      }
  120.    *argcp = argc;
  121.  
  122.    return argv;
  123. }
  124.    
  125. static int interp_select_box (void) /*{{{*/
  126. {
  127.    unsigned int n;
  128.    Slrn_Select_Box_Type box;
  129.    int ret;
  130.  
  131.    if (Slrn_Batch)
  132.      {
  133.     slrn_error ("select box function not available in batch mode.");
  134.     return -1;
  135.      }
  136.  
  137.    if (NULL == (box.lines = pop_argv_list (&n)))
  138.      return -1;
  139.  
  140.    if (-1 == SLpop_string (&box.title))
  141.      {
  142.     free_argv_list (box.lines, n);
  143.     return -1;
  144.      }
  145.    
  146.    ret = slrn_select_box (&box);
  147.    free_argv_list (box.lines, n);
  148.    slrn_free (box.title);
  149.    
  150.    return ret;
  151. }
  152.  
  153. /*}}}*/
  154.  
  155. static void select_list_box (void)
  156. {
  157.    char *title;
  158.    unsigned int argc;
  159.    char **argv;
  160.    int active;
  161.    int ret;
  162.  
  163.    if (-1 == SLang_pop_integer (&active))
  164.      return;
  165.    
  166.    argv = pop_argv_list (&argc);
  167.    if (argv == NULL)
  168.      return;
  169.    
  170.    if (-1 == SLpop_string (&title))
  171.      {
  172.     free_argv_list (argv, argc);
  173.     return;
  174.      }
  175.    
  176.    ret = slrn_select_list_mode (title, argc, argv, active - 1, NULL);
  177.    if (ret == -1)
  178.      {
  179.     SLang_push_string ("");
  180.     return;
  181.      }
  182.    
  183.    SLang_push_string (argv[ret]);
  184.  
  185.    slrn_free (title);
  186.    free_argv_list (argv, argc);
  187. }
  188.  
  189. static int get_yesno_cancel (char *prompt)
  190. {
  191.    return slrn_get_yesno_cancel ("%s", prompt);
  192. }
  193.  
  194. static int get_response (char *choices, char *prompt)
  195. {
  196.    return slrn_get_response (choices, "%s", prompt);
  197. }
  198.  
  199.    
  200. static void tt_send (char *s)
  201. {
  202.    if (Slrn_Batch == 0)
  203.      {
  204.     SLtt_write_string (s);
  205.     SLtt_flush_output ();
  206.      }
  207. }
  208.  
  209. /*}}}*/
  210.  
  211. /*{{{ File functions */
  212.  
  213. static void make_home_filename (char *name) /*{{{*/
  214. {
  215.    char file [SLRN_MAX_PATH_LEN];
  216.    slrn_make_home_filename (name, file);
  217.    SLang_push_string (file);
  218. }
  219.  
  220. /*}}}*/
  221.  
  222. static int evalfile (char *file)
  223. {
  224.    if (-1 == slrn_eval_slang_file (file))
  225.      return 0;
  226.  
  227.    return 1;
  228. }
  229.  
  230.  
  231. int slrn_eval_slang_file (char *name) /*{{{*/
  232. {
  233.    char file [SLRN_MAX_PATH_LEN];
  234.    
  235.    if (Slrn_Macro_Dir != NULL)
  236.      {
  237.     int n = 0;
  238.     char dir[SLRN_MAX_PATH_LEN];
  239.     
  240.     while (1)
  241.       {
  242.          if (-1 == SLextract_list_element (Slrn_Macro_Dir, n, ',',
  243.                            file, sizeof (file)))
  244.            break;
  245.          
  246.          slrn_make_home_dirname (file, dir);
  247.          if ((-1 != slrn_dircat (dir, name, file))
  248.          && (1 == slrn_file_exists (file)))
  249.            {
  250.           slrn_message_now ("loading %s", file);
  251.           if (-1 == SLang_load_file (file))
  252.             return -1;
  253.           return 0;
  254.            }
  255.          n++;
  256.       }
  257.      }
  258.    
  259.    slrn_make_home_filename (name, file);
  260.    slrn_message_now ("loading %s", file);
  261.    if (0 == SLang_load_file (file))
  262.      return -1;
  263.    return 0;
  264. }
  265.  
  266. /*}}}*/
  267.  
  268.  
  269.  
  270. /*}}}*/
  271.  
  272. /*{{{ Set/Get Variable Functions */
  273.  
  274. static void set_string_variable (char *s1, char *s2) /*{{{*/
  275. {
  276.    if (-1 == slrn_set_string_variable (s1, s2))
  277.      slrn_error ("%s is not a valid variable name.", s1);
  278. }
  279.  
  280. /*}}}*/
  281.  
  282. static void set_integer_variable (char *s1, int *val) /*{{{*/
  283. {
  284.    if (-1 == slrn_set_integer_variable (s1, *val))
  285.      slrn_error ("%s is not a valid variable name.", s1);
  286. }
  287.  
  288. /*}}}*/
  289.  
  290. static void get_variable_value (char *name) /*{{{*/
  291. {
  292.    char **s;
  293.    int *ip;
  294.    int type;
  295.    
  296.    if (-1 == slrn_get_variable_value (name, &type, &s, &ip))
  297.      {
  298.     slrn_error ("%s is not a valid variable name.", name);
  299.     return;
  300.      }
  301.    
  302.    if (type == STRING_TYPE)
  303.      {
  304.     char *str;
  305.     if ((s == NULL) || (*s == NULL)) str = "";
  306.     else str = *s;
  307.     SLang_push_string (str);
  308.      }
  309.    else if (type == INT_TYPE)
  310.      {
  311.     int i;
  312.     if (ip == NULL) i = 0; else i = *ip;
  313.     SLang_push_integer (i);
  314.      }
  315. }
  316.  
  317. /*}}}*/
  318.  
  319. /*}}}*/
  320.  
  321. static char *get_server_name (void) /*{{{*/
  322. {
  323.    if ((NULL == Slrn_Server_Obj) 
  324.        || (NULL == Slrn_Server_Obj->sv_name))
  325.      return "";
  326.    
  327.    return Slrn_Server_Obj->sv_name;
  328. }
  329.  
  330. /*}}}*/
  331. static void quit (int *code) /*{{{*/
  332. {
  333.    slrn_quit (*code);
  334. }
  335.  
  336. /*}}}*/
  337.    
  338. /*{{{ Keyboard related functions */
  339.  
  340. static void definekey (char *fun, char *key, char *map) /*{{{*/
  341. {
  342.    SLKeyMap_List_Type *kmap;
  343.    
  344.    if (NULL == (kmap = SLang_find_keymap (map)))
  345.      {
  346.     error ("definekey: no such keymap.");
  347.     return;
  348.      }
  349.    
  350.    if (0 != SLang_define_key (key, fun, kmap))
  351.      {
  352.      }
  353. }
  354.  
  355. /*}}}*/
  356.  
  357. static void undefinekey (char *key, char *map) /*{{{*/
  358. {
  359.    SLKeyMap_List_Type *kmap;
  360.    
  361.    if (NULL == (kmap = SLang_find_keymap (map)))
  362.      {
  363.     error ("undefinekey: no such keymap.");
  364.     return;
  365.      }
  366.    
  367.    SLang_undefine_key (key, kmap);
  368. }
  369.  
  370. /*}}}*/
  371.  
  372. static void generic_read_mini (int no_echo, char *prompt, char *dfl, char *init) /*{{{*/
  373. {
  374.    char str[256];
  375.    int ret;
  376.  
  377.    strncpy (str, init, sizeof (str));
  378.    str[sizeof(str) - 1] = 0;
  379.    
  380.    if (no_echo) 
  381.      ret = slrn_read_input_no_echo (prompt, dfl, str, 0, 0);
  382.    else 
  383.      ret = slrn_read_input (prompt, dfl, str, 0, 0);
  384.    
  385.    if (-1 == ret)
  386.      {
  387.     error ("Quit!");
  388.     return;
  389.      }
  390.    SLang_push_string (str);
  391. }
  392.  
  393. /*}}}*/
  394. static void read_mini (char *prompt, char *dfl, char *init) /*{{{*/
  395. {
  396.    generic_read_mini (0, prompt, dfl, init);
  397. }
  398.  
  399. /*}}}*/
  400. static void read_mini_no_echo (char *prompt, char *dfl, char *init) /*{{{*/
  401. {
  402.    generic_read_mini (1, prompt, dfl, init);
  403. }
  404.  
  405. /*}}}*/
  406.  
  407. static void set_prefix_arg (int *arg) /*{{{*/
  408. {
  409.    slrn_set_prefix_argument (*arg);
  410. }
  411.  
  412. /*}}}*/
  413.  
  414. static int get_prefix_arg (void) /*{{{*/
  415. {
  416. #define NO_PREFIX_ARGUMENT -1
  417.  
  418.    return Slrn_Prefix_Arg_Ptr ? *Slrn_Prefix_Arg_Ptr : NO_PREFIX_ARGUMENT;
  419.  
  420. /*}}}*/
  421.  
  422. static void reset_prefix_arg (void) /*{{{*/
  423. {
  424.    Slrn_Prefix_Arg_Ptr = NULL;
  425. }
  426.   
  427. /*}}}*/
  428.  
  429.  
  430. static int check_tty (void)
  431. {
  432.    if (Slrn_TT_Initialized & SLRN_TTY_INIT)
  433.      return 0;
  434.    
  435.    error ("Terminal not initialized.");
  436.    return -1;
  437. }
  438.  
  439. static int input_pending (int *tsecs)
  440. {
  441.    if (check_tty ())
  442.      return 0;
  443.    
  444.    return SLang_input_pending (*tsecs);
  445. }
  446.  
  447. static int getkey (void)
  448. {
  449.    if (check_tty ())
  450.      return 0;
  451.    
  452.    return SLang_getkey ();
  453. }
  454.  
  455. static void ungetkey (int *c)
  456. {
  457.    if (check_tty ())
  458.      return;
  459.  
  460.    SLang_ungetkey (*c);
  461. }
  462.  
  463. static void set_input_string (